import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.hibernate.Criteria;
import org.hibernate.Session;

public class Controller extends HttpServlet
{
	private static final long		serialVersionUID	= 3077742467365143107L;
	public final static int			SUCCESS				= 1;
	public final static int			FAIL				= 0;
	private PrintWriter				out;
	private Session					session;
	private HashMap<String, String>	request				= new HashMap<String, String>();

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		if ( !request.getRequestURI().equals("/miat/login") )
		{
			HttpSession httpSession = request.getSession(true);
			Long userId = (Long) httpSession.getAttribute("user");
			if ( userId == null )
			{
				response.sendRedirect("/miat/login");
				return;
			}
		}
		response.setContentType("text/html; charset=UTF-8");
		if ( request.getQueryString() != null )
			for (String query : URLDecoder.decode(request.getQueryString(), "UTF-8").split("\\&"))
			{
				if ( query.split("\\=").length == 2 )
					getRequest().put(query.split("\\=")[0], query.split("\\=")[1]);
			}

		setOut(new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "UTF8"), true));
		setSession(HibernateUtil.currentSession());

		String action = request.getParameter("action");
		if ( action == null )
		{
			Method method;
			try
			{
				method = this.getClass().getMethod("index", HttpServletRequest.class, HttpServletResponse.class);
				method.invoke(this, request, response);
			}
			catch (SecurityException e)
			{
				e.printStackTrace();
			}
			catch (NoSuchMethodException e)
			{
				e.printStackTrace();
			}
			catch (IllegalArgumentException e)
			{
				e.printStackTrace();
			}
			catch (IllegalAccessException e)
			{
				e.printStackTrace();
			}
			catch (InvocationTargetException e)
			{
				e.printStackTrace();
			}
		}
		else
		{
			Method method;
			try
			{
				method = this.getClass().getMethod(action, HttpServletRequest.class, HttpServletResponse.class);
				method.invoke(this, request, response);
			}
			catch (SecurityException e)
			{
				e.printStackTrace();
			}
			catch (NoSuchMethodException e)
			{
				e.printStackTrace();
			}
			catch (IllegalArgumentException e)
			{
				e.printStackTrace();
			}
			catch (IllegalAccessException e)
			{
				e.printStackTrace();
			}
			catch (InvocationTargetException e)
			{
				e.printStackTrace();
			}
		}
		// Statics.initDb(HibernateUtil.currentSession(), getServletContext());
	}

	public PrintWriter getOut()
	{
		return out;
	}

	public void setOut(PrintWriter out)
	{
		this.out = out;
	}

	public Session getSession()
	{
		return session;
	}

	public void setSession(Session session)
	{
		this.session = session;
	}

	public void renderView(String html) throws UnsupportedEncodingException, IOException
	{
		getOut().println(html);
		getOut().flush();
	}

	public void renderView(String html, HttpServletResponse response) throws UnsupportedEncodingException, IOException
	{
		// getOut().println(html);
		PrintWriter out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "UTF8"), true);
		out.println(html);
		out.flush();
	}

	public void renderViewErrorWrongUrl()
	{
		getOut().print("Wrong URL!");
	}

	public String getViewHtml(String category, String view)
	{
		return StaticMethods.getHTML(getServletContext(), "/jsp/" + category + "/" + view + ".html");
	}

	public String getViewHtmlFormUrl(String url)
	{
		return StaticMethods.getHTML(url);
	}

	@SuppressWarnings("rawtypes")
	public Object getObjectByPk(Class class1, long pk)
	{
		// Criteria criteria = getSession().createCriteria(class1);
		// Criterion criterion = Restrictions.idEq(pk);
		// criteria.add(criterion);
		// return criteria.uniqueResult();
		return getSession().load(class1, pk);
	}

	@SuppressWarnings("rawtypes")
	public List getAllObjects(Class class1)
	{
		Criteria criteria = getSession().createCriteria(class1);
		return criteria.list();
	}

	public String getParameter(String arg) throws UnsupportedEncodingException
	{
		if ( getRequest().containsKey(arg) )
			return getRequest().get(arg);
		return null;
	}

	public HashMap<String, String> getRequest()
	{
		return request;
	}

	public void setRequest(HashMap<String, String> request)
	{
		this.request = request;
	}
}
